package xj.graph2d.shapes;

import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;

import xj.graph2d.TwoEndsShape;

public class RegularPolygonShape 
  extends PolygonShape 
  implements TwoEndsShape, ShapeConstants {

  public RegularPolygonShape() {
    this(0, 0, 0, 0, BOX_SHAPE, NORTH, false);
  }

  public RegularPolygonShape(float x1, float y1, float x2, float y2,
			     int shapeType) {
    this(x1, y1, x2, y2, shapeType, NORTH, false);
  }

  public RegularPolygonShape(float x1, float y1, float x2, float y2,
			     int shapeType, boolean filled) {
    this(x1, y1, x2, y2, shapeType, NORTH, filled);
  }

  public RegularPolygonShape(float x1, float y1, float x2, float y2,
			     int shapeType, int direction) {
    this(x1, y1, x2, y2, shapeType, direction, false);
  }

  public RegularPolygonShape(float x1, float y1, float x2, float y2,
			     int shapeType, int direction, boolean filled) {
    super(filled);
    if (shapeType >= 0 && shapeType < points.length) {
      float width = Math.abs(x1 - x2);
      float height = Math.abs(y1 - y2);
      float x = Math.min(x1, x2);
      float y = Math.min(y1, y2);
      this.shapeType = shapeType;
      this.direction = direction;
      setShape(x, y, width, height, shapeType, direction);
    }
  }

  @Override
  public boolean isEdgeSensitive() {
    return true;
  }

  @Override
  public boolean isCornorSensitive() {
    return true;
  }

  protected void setShape(int shapeType, int direction) {
    Rectangle2D bounds = getBounds();
    setShape((float) bounds.getX(), (float) bounds.getY(), 
	     (float) bounds.getWidth(), (float) bounds.getHeight(), 
	     shapeType, direction);
  }

  protected void setShape(float x, float y, float width, float height,
			  int shapeType, int direction) {
    int n = points[shapeType].length;
    float cx; // = x + width * points[shapeType][0];
    float cy; // = y + height * points[shapeType][1];
    for (int i = 0; i < n; i += 2) {
      float px = points[shapeType][i];
      float py = points[shapeType][i + 1];
      if (direction == SOUTH) {
	py = 1 - py;
      } else if (direction == EAST || direction == WEST) {
	float t = px;
	px = py;
	py = t;
	if (direction == EAST) {
	  px = 1 - px;
	}
      }
      cx = x + width * px;
      cy = y + height * py;
      if (i == 0) {
	setStart(cx, cy);
      } else {
	addPoint(cx, cy, true);
      }
    }
    calculateBounds();
  }

  public int getDirection() {
    return direction;
  }

  public int getShapeType() {
    return shapeType;
  }

  public void setDirection(int direction) {
    if (direction != this.direction) {
      this.direction = direction;
      setShape(this.shapeType, this.direction);
    }
  }

  public void setShapeType(int shapeType) {
    if (shapeType != this.shapeType) {
      this.shapeType = shapeType;
      setShape(this.shapeType, this.direction);
    }
  }

  @Override
  protected Map<String, Object> getXMLAttributes() {
    Map<String, Object> attrs = super.getXMLAttributes();
    if (attrs == null) {
      attrs = new HashMap<String, Object>();
    }
    attrs.put("type", shapeType);
    attrs.put("direction", direction);
    attrs.put("filled", filled);
    attrs.put("showBorder", showborder);
    return attrs;
  }

  @Override
  protected void processXMLAttributes(org.w3c.dom.Element node) {
    if (node != null) {
      super.processXMLAttributes(node);

      String s;
      s = node.getAttribute("type");
      try {
	shapeType = Integer.parseInt(s);
      } catch (NumberFormatException ex) {
      }
      s = node.getAttribute("direction");
      try {
	direction = Integer.parseInt(s);
      } catch (NumberFormatException ex) {
      }

      s = node.getAttribute("filled");
      filled = Boolean.valueOf(s);
      s = node.getAttribute("showBorder");
      showborder = Boolean.valueOf(s);
    }
  }

  protected int direction;

  protected int shapeType;

  protected static final int defaultWidth = 40;

  protected static final int defaultHeight = 30;

}
